#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDir>
#include <QDebug>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QTimer>
#include <QTime>
#include <QSlider>

QString secondsToMinSec(qint64);

QString secondsToMinSec(qint64 totalSeconds) {
    // 把总秒数换成 分：秒 形式
    // e.g. 100->1:40

    int hours = totalSeconds / 3600;
    int minutes = (totalSeconds % 3600) / 60;
    int seconds = totalSeconds % 60;

    QTime time(hours, minutes, seconds);

    return time.toString((hours > 0) ? "h:mm:ss" : "m:ss");
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("Qt 音乐播放器");

    initButton();
    initTree();
    initPlayer();

    initSlider();
    initLabel();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initLabel(){
//    ui->volumeLabel->setStyleSheet("background-color: white;");
    ui->volumeLabel->setScaledContents(true); // 设置图片自适应大小
    volumePic = new QPixmap(":pic/volume_1.png");
    ui->volumeLabel->setPixmap(*volumePic);
}

void MainWindow::initButton(){
}

void MainWindow::initTree() {
    connect(ui->treeWidget,&QTreeWidget::itemDoubleClicked,this,&MainWindow::onItemDoubleClicked);
}

void MainWindow::initPlayer(){
    audioOutput = new QAudioOutput(this);
    audioOutput->setVolume(1.0); // 最大音量（0.0~1.0）

    player = new QMediaPlayer(this);
    player->setProperty("musicId",-1); // 通过这个设置，来记录当前播放的歌曲id是多少
    player->setAudioOutput(audioOutput);

    // 实现playbutton的字样随音乐播放而动态改变
    connect(player,&QMediaPlayer::playingChanged,this,&MainWindow::updatePlayButton);

    // 实现自动播放下一首
    connect(player,&QMediaPlayer::mediaStatusChanged,this,&MainWindow::handlePlayingStatusChanged);

    // 实现对音量改变而处理图片变化
    connect(audioOutput,&QAudioOutput::volumeChanged,this,[this](float value){
        if (value <= 0) volumePic->load(":/pic/volume_0.png");
        else volumePic->load(":/pic/volume_1.png");

        ui->volumeLabel->setPixmap(*volumePic);
    });
}

void MainWindow::initSlider(){
    // 初始化Slider
    ui->musicSlider->setMinimum(0);
    ui->musicSlider->setMaximum(0);
    ui->volumeSlider->setMaximum(100);
    ui->volumeSlider->setValue(100);

    //初始化Label
    ui->startLabel->setText("00:00");
    ui->endLabel->setText("00:00");

    // 应该是创建了一个线程，与主线程并行
    updateTimer = new QTimer(this);
    updateTimer->setInterval(1000);
    connect(updateTimer,&QTimer::timeout,this,&MainWindow::updateMusicSlider);

    // 绑定播放器
    // 感觉很巧妙这里，把接口向外
    connect(player,&QMediaPlayer::durationChanged,this,[this](qint64 duration){
//        qDebug() << duration ;
        ui->musicSlider->setMaximum(duration);
        ui->endLabel->setText(secondsToMinSec(duration/1000));
    });

    // 处理拖拽
    connect(ui->musicSlider,&QSlider::sliderMoved,this,[this](qint64 value){
        player->setPosition(value);
        ui->startLabel->setText(secondsToMinSec(value/1000));
    });

    connect(ui->volumeSlider,&QSlider::sliderMoved,this,[this](float value){
        audioOutput->setVolume(value/100);
    });
}


void MainWindow::updatePlayButton(bool playing){
    // 通过获取player->playingChanged的信号，用于改变playButton，和musicSlider
    if (playing){
        ui->playButton->setText("暂停");
        updateTimer->start();
    }
    else{
        ui->playButton->setText("播放");  //更新按钮文本
        updateTimer->stop();
    }
}

void MainWindow::updateTree(const QFileInfoList& fileList){
    ui->treeWidget->clear();
    int idx = 0;

    for (const QFileInfo &fileInfo : fileList){
//        qDebug() << fileInfo.baseName();
        QTreeWidgetItem* songItem = new QTreeWidgetItem();
        songItem->setText(0,QString::number(++idx));
        songItem->setText(1,fileInfo.completeBaseName());
        ui->treeWidget->addTopLevelItem(songItem);
    }
    // 有一个弊端，就是我new了之后没法删除，怎么办
    // 1.构建songItemList全局变量，以再指定位置手动删除
    // 2.使用addTopLevelItem,以及clear，自动清除
}

void MainWindow::updateMusicSlider(){
    if(!ui->musicSlider->isSliderDown()){ //用户未拖动
        ui->musicSlider->setValue(player->position());
        ui->startLabel->setText(secondsToMinSec(player->position()/1000));
    }
}


void MainWindow::on_openFileButton_clicked()
{
    QString folderPath = QFileDialog::getExistingDirectory(
        this,
        "选择音乐文件夹",
        "D:\\Document\\Code\\C++\\Little_Project\\music",
        QFileDialog::ReadOnly | QFileDialog::ShowDirsOnly
    );

    if (folderPath.isEmpty()) {
        QMessageBox::information(this, "提示", "未选择文件夹");
        return;
    }

    player->setProperty("musicId",-1);

    QDir dir(folderPath);
    dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
    dir.setNameFilters({"*.mp3", "*.flac", "*.wav", "*.aac", "*.m4a"});

    musicList = dir.entryInfoList();
    updateTree(musicList);
}

void MainWindow::on_playButton_clicked()
{
    // 实现从Tree中获取歌曲信息，并且开始播放音乐
    // 需要安装 QMediaPlayer , 在.pro文件中 添加 QT += multimedia
    // 当下无法完成对.mp3文件的播放？
    // 现在解决对无法播放mp3文件的问题
    // 其实是QMediaPlayer 对特殊MP3，如自带封面的MP3文件无法处理，导致无法播放。
    // 不好解决，如果要解决，方便的以及我会的就是用 ffmpeg 把音频文件去掉cover

    QList<QTreeWidgetItem*> onList = ui->treeWidget->selectedItems();
    if (onList.empty()){
        qDebug() << "未选中任何歌曲，无法播放";
        return;
    }

    int id = onList[0]->text(0).toInt()-1;
    player->setProperty("musicId",id);

    // 判断是要暂停，播放，还是要播放另外一首歌。用绝对路径判断是否为相同歌。
    QString musicPath = musicList[id].absoluteFilePath();

    if (player->source() != QUrl::fromLocalFile(musicPath)) {
        // 不相同，就播放另外一首歌。
        playMusic();
        return;
    }

    // 相同的话，判断是要暂停还是要继续播放。
    switch(player->playbackState()){
        case(QMediaPlayer::PlayingState):{
            player->pause();
            break;
        }
        case(QMediaPlayer::PausedState):{}
        case(QMediaPlayer::StoppedState):{
            player->play();
        }
    }
}

void MainWindow::onItemDoubleClicked(QTreeWidgetItem* item){
   player->setProperty("musicId",item->text(0).toInt()-1);
   playMusic();
}

void MainWindow::on_LastButton_clicked()
{
   int id = player->property("musicId").toInt();

   if (id < 0) return;
   else if(id == 0) id = musicList.length() - 1;
   else id -= 1;

   player->setProperty("musicId",id);
   playMusic();
}

void MainWindow::on_PassButton_clicked()
{
    int id = player->property("musicId").toInt();

    if (id < 0) return;
    else if(id == musicList.length() - 1) id = 0;
    else id += 1;

    player->setProperty("musicId",id);
    playMusic();
}

void MainWindow::playMusic(){
    //切换音乐的时候，会启用该函数

//    qDebug() << player->property("musicId").toInt();
    QFileInfo musicInfo = musicList[player->property("musicId").toInt()];
    QString musicPath = musicInfo.absoluteFilePath();

    if (!QFile::exists(musicPath)) {  //检查文件是否存在
        QMessageBox::warning(this, "提示", "音乐文件不存在，请检查路径");
        return;
    }

    qDebug() << "正在播放: " << musicPath;
    player->setSource(QUrl::fromLocalFile(musicPath));
    ui->musicNameLabel->setText(musicInfo.completeBaseName());
    player->play();
}


void MainWindow::handlePlayingStatusChanged(QMediaPlayer::MediaStatus status){
    if (status == QMediaPlayer::EndOfMedia){
        on_PassButton_clicked();
    }
}
